package model;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.table.AbstractTableModel;

import domain.Library;
import domain.Loan;

public class LoanMasterLoanTableModel extends AbstractTableModel implements Observer {
    private static LoanMasterLoanTableModel instance;
    private String[] columns = { "Status", "ID", "Titel", "Ausgeliehen bis", "Ausgeliehen an" };
    private List<Loan> model;
    private final Library library;
    private static final long serialVersionUID = 2966279676059941187L;
    DateFormat dateFormat = SimpleDateFormat.getDateInstance();

    public static LoanMasterLoanTableModel getInstance() {
        if (instance == null)
            instance = new LoanMasterLoanTableModel();
        return instance;
    }

    private LoanMasterLoanTableModel() {
        library = Library.getInstance();
        library.addObserver(this);
        model = new ArrayList<Loan>(library.getOpenLoans());
        this.update(null, null);
    }

    @Override
    public void update(Observable obj, Object arg1) {
        List<Loan> modelOld = model;
        model = new ArrayList<Loan>(library.getOpenLoans());
        for (int i = 0; i < model.size(); i++) {
            if (!modelOld.contains(model.get(i))) {
                this.fireTableRowsInserted(i, i);
            }
        }
        for (int i = 0; i < modelOld.size(); i++) {
            if (!model.contains(modelOld.get(i))) {
                this.fireTableRowsDeleted(i, i);
            }
        }
    }

    @Override
    public boolean isCellEditable(int arg0, int arg1) {
        return false;
    }

    @Override
    public String getColumnName(int column) {
        return columns[column];
    }

    @Override
    public int getColumnCount() {
        return columns.length;
    }

    @Override
    public int getRowCount() {
        return model.size();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Loan loan;
        loan = model.get(rowIndex);
        switch (columnIndex) {
            case 0:
                return getState(loan);
            case 1:
                return loan.getCopy().getInventoryNumber();
            case 2:
                return loan.getCopy().getTitle();
            case 3:
                return getDueDate(loan);
            case 4:
                return loan.getCustomer().getSurname() + " " + loan.getCustomer().getName();
            default:
                return null;
        }
    }

    private String getState(Loan loan) {
        if (loan.isOverdue()) {
            return "⚠ fällig";
        } else {
            return "✔ ok";
        }
    }

    private String getDueDate(Loan loan) {
        if (loan == null) {
            return null;
        } else if (loan.isOverdue()) {
            return dateFormat.format(loan.getDueDate().getTime()) + " (seit " + loan.getDaysOverdue() + " Tagen)";
        } else {
            return dateFormat.format(loan.getDueDate().getTime()) + " (noch " + loan.getDaysLeft() + " Tage)";
        }
    }

    public Loan getElementAt(int rowIndex) {
        return model.get(rowIndex);
    }

    @Override
    public Class<String> getColumnClass(int columnIndex) {
        return String.class;
    }

}
